package com.leon.datalink.core.persistence.adapter;

import akka.persistence.journal.EventAdapter;
import akka.persistence.journal.EventSeq;
import com.leon.datalink.core.persistence.event.NodeEvent;
import com.leon.datalink.core.serializer.ProtostuffSerializable;
import com.leon.datalink.core.utils.ProtostuffUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Protostuff事件适配器
 * 用于序列化和反序列化持久化事件
 * 
 * @author leon
 */
public class ProtostuffEventAdapter implements EventAdapter {
    
    private static final Logger logger = LoggerFactory.getLogger(ProtostuffEventAdapter.class);
    
    @Override
    public String manifest(Object event) {
        if (event instanceof NodeEvent) {
            return event.getClass().getName();
        }
        return "";
    }
    
    @Override
    public Object toJournal(Object event) {
        if (event instanceof ProtostuffSerializable) {
            try {
                // 使用Protostuff序列化
                byte[] serialized = ProtostuffUtils.serialize(event);
                return new SerializedEvent(event.getClass().getName(), serialized);
            } catch (Exception e) {
                logger.error("Failed to serialize event: {}", event, e);
                throw new RuntimeException("Event serialization failed", e);
            }
        }
        return event;
    }
    
    @Override
    public EventSeq fromJournal(Object event, String manifest) {
        if (event instanceof SerializedEvent) {
            SerializedEvent serializedEvent = (SerializedEvent) event;
            try {
                // 使用Protostuff反序列化
                Class<?> eventClass = Class.forName(serializedEvent.className);
                Object deserializedEvent = ProtostuffUtils.deserialize(
                    serializedEvent.data, eventClass);
                return EventSeq.single(deserializedEvent);
            } catch (Exception e) {
                logger.error("Failed to deserialize event: {}", serializedEvent.className, e);
                throw new RuntimeException("Event deserialization failed", e);
            }
        }
        return EventSeq.single(event);
    }
    
    /**
     * 序列化事件包装类
     */
    public static class SerializedEvent implements ProtostuffSerializable {
        private String className;
        private byte[] data;
        
        public SerializedEvent() {
            // 默认构造函数，用于序列化
        }
        
        public SerializedEvent(String className, byte[] data) {
            this.className = className;
            this.data = data;
        }
        
        public String getClassName() {
            return className;
        }
        
        public void setClassName(String className) {
            this.className = className;
        }
        
        public byte[] getData() {
            return data;
        }
        
        public void setData(byte[] data) {
            this.data = data;
        }
    }
}
